package br.com.petsis.funcionalidades.manterPedido;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;

import br.com.petsis.conversores.ConversorMonetario;
import br.com.petsis.entity.Cliente;
import br.com.petsis.entity.Empresa;
import br.com.petsis.entity.FormaPagamento;
import br.com.petsis.entity.Pacote;
import br.com.petsis.entity.Pedido;
import br.com.petsis.entity.PedidoPet;
import br.com.petsis.entity.PedidoProduto;
import br.com.petsis.entity.PedidoServico;
import br.com.petsis.entity.Pet;
import br.com.petsis.entity.Produto;
import br.com.petsis.entity.Servico;
import br.com.petsis.utilitarios.UtilDate;
import br.com.petsis.utilitarios.UtilString;
import br.com.petsis.vo.ConsultaClientesVO;
import br.com.petsis.vo.OrdemServicoVO;

@Name("manterPedidoController")
@Scope(ScopeType.CONVERSATION)
//@Restrict(value="#{identity.hasRole('Administrador')}")
public class ManterPedidoController {
	
	private static final String PRODUTO_NAO_ENCONTRADO = "PRODUTO NÃO ENCONTRADO";
	
	private static final String QRY_CLIENTES = "select c from Cliente c left join c.pets p where c.empresa.idEmpresa = :idEmpresa and c.flgAtivo = 'T'";
	private static final String QRY_PETS = "select p from Pet p where p.cliente.idCliente = :idCliente and p.flgAtivo = 'T'";
	private static final String QRY_PRODUTOS = "select p from Produto p where p.empresa.idEmpresa = :idEmpresa and p.flgAtivo = 'T'";
	private static final String QRY_SERVICOS = "select s from Servico s where s.empresa.idEmpresa = :idEmpresa and s.flgAtivo = 'T'";
	private static final String QRY_PEDIDOS_DO_DIA = "select p.id_pedido,p.id_forma_pagamento,p.id_cliente,p.vlr_pedido,p.flg_pago from pedido p where p.id_empresa = :idEmpresa and DATE(p.dta_pedido) = DATE(:dtaPedido)";
	private static final String QRY_SERVICOS_PEDIDO = "select s from PedidoServico s where s.pedido.idPedido = :idPedido";
	private static final String QRY_PRODUTOS_PEDIDO = "select p from PedidoProduto p where p.pedido.idPedido = :idPedido";
	private static final String QRY_PACOTE_CLIENTE = "select p from Pacote p where p.cliente.idCliente = :idCliente and p.dtaInicio <= :dtaPedido and p.dtaFim >= :dtaPedido and p.flgAtivo = 'T'";
	private static final String QRY_FORMA_PAGAMENTO = "select f from FormaPagamento f ";
	
	private static final String PARAMETER_ID_CLIENTE = "idCliente";
	private static final String PARAMETER_ID_EMPRESA = "idEmpresa";
	private static final String PARAMETER_DTA_PEDIDO = "dtaPedido";
	private static final String PARAMETER_ID_PEDIDO = "idPedido";
	
	@In(create=true)
	private EntityManager entityManager;
	
	private Pedido pedidoEdicao;
	
	private Produto produtoPesquisa;
	
	private String nomeServicoPesquisa;
	
	private PedidoProduto produtoSelecionado;

	private PedidoServico servicoSelecionado;
	
	private PedidoPet pedidoPet;
	
	private Cliente clienteSelecionado;
	
	private Date dataPedido;
	
	private Cliente clienteDetalhe;
	
	private List<Cliente> listaClientes;
	
	private List<SelectItem> listaPets;
	
	private List<Produto> listaProdutos;
	
	private List<Servico> listaServicos;
	
	private List<Pedido> listaPedidos;
	
	private List<PedidoServico> listaPedidoServicos;
	
	private List<PedidoProduto> listaPedidoProdutos;
	
	private Integer numeroPedido;
	
	private boolean selecionadoTodosServicos;
	
	private boolean selecionadoTodosProdutos;
	
	private boolean selecionadoTodosPedidos;
	
	private List<PedidoProduto> produtosExclusao;
	
	private List<PedidoServico> servicosExclusao;
	
	private Pacote pacoteDisponivel = null;
	
	private boolean pacote;
	
	private Integer indexProduto;
	
	private ConsultaClientesVO parametrosClientes;
	
	private OrdemServicoVO ordemServico;
	
	private float valorFinal;

	private Float valorRecebido;
	
	private String alert;
	
	private boolean exibePopupAviso;
	
	@In(required=false)
	private Empresa empresaSessao;
	
	public boolean isExibePopupAviso() {
		return exibePopupAviso;
	}

	public void setExibePopupAviso(boolean exibePopupAviso) {
		this.exibePopupAviso = exibePopupAviso;
	}

	public String getAlert() {
		return alert;
	}

	public void setAlert(String alert) {
		this.alert = alert;
	}
	
	public boolean isPacote() {
		return pacote;
	}

	public void setPacote(boolean pacote) {
		this.pacote = pacote;
	}

	public ConsultaClientesVO getParametrosClientes() {
		if (parametrosClientes == null) {
			parametrosClientes = new ConsultaClientesVO();
		}
		return parametrosClientes;
	}

	public void setParametrosClientes(ConsultaClientesVO parametrosClientes) {
		this.parametrosClientes = parametrosClientes;
	}

	public void onLoad(){
		produtosExclusao = new ArrayList<PedidoProduto>();
		servicosExclusao = new ArrayList<PedidoServico>();
		pedidoEdicao = new Pedido();
		pedidoEdicao.setDtaPedido(new Date());
		pedidoEdicao.setCliente(new Cliente());
		pedidoEdicao.setNroPedido(1);
		pedidoEdicao.setTpoPedido('P');
		setListaPedidos(null);
		setDataPedido(UtilDate.getDataAtual());
		if(empresaSessao == null){
			pedidoEdicao.setNroPedido(0);
			return;
		}
		Integer ultimoNroPedido = (Integer)entityManager.createQuery("select MAX(p.nroPedido) from Pedido p where p.empresa.idEmpresa = :idEmpresa and DATE(p.dtaPedido) = DATE(:data)")
			.setParameter("data", new Date())
			.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
			.getSingleResult();
		if(ultimoNroPedido != null){
			pedidoEdicao.setNroPedido(ultimoNroPedido+1);
		}else{
			pedidoEdicao.setNroPedido(1);
		}
		/*for(Pedido p : getListaPedidos()){
			if(pedidoEdicao.getNroPedido().equals(p.getNroPedido())){
				pedidoEdicao.setNroPedido(p.getNroPedido()+1);
			}
		}*/
		if (getListaPedidoProdutos().size() < 1) {
			novoProduto();
		}
	}
	
	public void atualizaListaPets(){
		if(getPedidoEdicao().getCliente() != null &&
				getPedidoEdicao().getCliente().getIdCliente() != null){
			setListaPets(null);
			List<Pet> pets = entityManager.createQuery(QRY_PETS)	
				.setParameter(PARAMETER_ID_CLIENTE, getPedidoEdicao().getCliente().getIdCliente())
				.getResultList();
			if(pets != null && pets.size() > 0){
				for(Pet p : pets){
					getListaPets().add(new SelectItem(p.getIdPet(),p.getDscNome()+" - "+p.getRaca().getDscNome()));
				}
			}else{
				setListaPets(new ArrayList<SelectItem>());
				getListaPets().add(new SelectItem(null,"Selecione"));
			}
			
			try{
				pacoteDisponivel = (Pacote)entityManager.createQuery(QRY_PACOTE_CLIENTE)
					.setParameter(PARAMETER_ID_CLIENTE, getPedidoEdicao().getCliente().getIdCliente())
					.setParameter(PARAMETER_DTA_PEDIDO, pedidoEdicao.getDtaPedido())
					.getSingleResult();
			}catch(NoResultException e){
				pacoteDisponivel = null;
				setPacote(false);
			}
		}
	}
	
	public void atualizaValorServico(PedidoServico servico){
		if(servico.getServico().getIdServico() != null){
			Servico serv = entityManager.find(Servico.class, servico.getServico().getIdServico());
			/*if(isPacote()){
				servico.setVlrServico(0F);
			}else{*/
				servico.setVlrServico(serv.getVlrServico());
//			}
		}
		atualizaValorTotalPedido();
	}
	
	public void atualizaValorProduto(PedidoProduto produto){
		if(produto.getProduto().getIdProduto() != null){
			Produto prod = entityManager.find(Produto.class, produto.getProduto().getIdProduto());
			produto.setVlrProduto(prod.getVlrProduto());
			produto.getProduto().setVlrProdutoCusto(prod.getVlrProdutoCusto());
			produto.getProduto().setQtdEstoque(prod.getQtdEstoque());
			if(prod.getPrzValidade() != null && 
					UtilDate.data1MenorQueData2(prod.getPrzValidade(), new Date())){
				produto.setMostraMsgValidade(true);
			}else{
				produto.setMostraMsgValidade(false);
			}
		}
		atualizaValorTotalPedido();
	}
	
	public void atualizaValorTotalPedido(){
		getPedidoEdicao().setVlrPedido(0F);
		if(!isPacote()){
			for(PedidoServico s : getListaPedidoServicos()){
				getPedidoEdicao().setVlrPedido(getPedidoEdicao().getVlrPedido() + s.getVlrServico());
			}
		}
		
		for(PedidoProduto p : getListaPedidoProdutos()){
			getPedidoEdicao().setVlrPedido(getPedidoEdicao().getVlrPedido() + (p.getVlrProduto() * p.getQtdeProduto()));
		}
		getPedidoEdicao().setVlrDesconto(getPedidoEdicao().getVlrPedido());
	}
	
	public void calculaDescontoServico(PedidoServico servico){
		if(servico.getDesconto() >= 0F){
			float percent = servico.getDesconto()/100;
			servico.setVlrServico((1 - percent)*servico.getServico().getVlrServico());
		}
		atualizaValorTotalPedido();
	}
	
	public void calculaDescontoProduto(PedidoProduto produto){
		if(produto.getDesconto() >= 0F){
			float percent = produto.getDesconto()/100;
			produto.setVlrProduto((1 - percent)*produto.getProduto().getVlrProduto());
		}
		atualizaValorTotalPedido();
	}
	
	public void calculaDescontoPedido(){
		if(getPedidoEdicao().getDesconto() >= 0F){
			float percent = getPedidoEdicao().getDesconto()/100;
				getPedidoEdicao().setVlrPedido((1 - percent)*getPedidoEdicao().getVlrDesconto());
		}
	}
	
	
	public List<FormaPagamento> buscaFormaPagamento() {
		return entityManager.createQuery(QRY_FORMA_PAGAMENTO).getResultList();
	}
	
	public Pedido getPedidoEdicao() {
		if (pedidoEdicao == null) {
			pedidoEdicao = new Pedido();
			pedidoEdicao.setFlgPago('T');
		}
		return pedidoEdicao;
	}

	public void setPedidoEdicao(Pedido pedidoEdicao) {
		this.pedidoEdicao = pedidoEdicao;
	}

	public List<Cliente> getListaClientes() {
		if (listaClientes == null) {
			listaClientes = new ArrayList<Cliente>();
		}
		return listaClientes;
	}

	public void setListaClientes(List<Cliente> listaClientes) {
		this.listaClientes = listaClientes;
	}

	public List<SelectItem> getListaPets() {
		if (listaPets == null) {
			listaPets = new ArrayList<SelectItem>();
			listaPets.add(new SelectItem(null,"Selecione"));
		}

		return listaPets;
	}

	public void setListaPets(List<SelectItem> listaPets) {
		this.listaPets = listaPets;
	}

	public List<Produto> getListaProdutos() {
		if (listaProdutos == null) {
			listaProdutos = new ArrayList<Produto>();
		}
		return listaProdutos;
	}

	public void setListaProdutos(List<Produto> listaProdutos) {
		this.listaProdutos = listaProdutos;
	}

	public List<Servico> getListaServicos() {
		if (listaServicos == null) {
			listaServicos = new ArrayList<Servico>();
		}
		return listaServicos;
	}

	public void setListaServicos(List<Servico> listaServicos) {
		this.listaServicos = listaServicos;
	}

	public List<Pedido> getListaPedidos() {
		if (listaPedidos == null) {
			listaPedidos = new ArrayList<Pedido>();
			if(empresaSessao != null){
				List<Object[]> lista = entityManager.createNativeQuery(QRY_PEDIDOS_DO_DIA)
					.setParameter(PARAMETER_DTA_PEDIDO, UtilDate.getDataAtual())
					.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
					.getResultList();
				Pedido p;
				for(Object[] o : lista){
					p = new Pedido();
					p.setIdPedido(Integer.parseInt(o[0].toString()));
					p.setVlrPedido(o[3] != null ? Float.parseFloat(o[3].toString()) : null);
					p.setFlgPago(o[4] != null ? (Character)o[4] : null);
					FormaPagamento pf = new FormaPagamento();
					pf.setDscFormaPagamento(o[1] != null ? recuperaDescricaoFormaPagamento(Integer.parseInt(o[1].toString())) : null);
					pf.setIdFormaPagamento(o[1] != null ? Integer.parseInt(o[1].toString()) : null);
					p.setFormaPagamento(pf);
					Cliente c = new Cliente();
					c.setDscNome(o[2] != null ? recuperaNomeCliente(Integer.parseInt(o[2].toString())) : null);
					c.setIdCliente(o[2] != null ? Integer.parseInt(o[2].toString()) : null);
					p.setCliente(c);
					listaPedidos.add(p);
				}
			}
		}
		return listaPedidos;
	}
	
	private String recuperaDescricaoFormaPagamento(Integer id){
		try {
			Object retorno = entityManager.createNativeQuery("select dsc_forma_pagamento from forma_pagamento where id_forma_pagamento = :id")
				.setParameter("id", id)
				.getSingleResult();
			return retorno != null ? retorno.toString() : null;
		} catch (NoResultException e) {
			return null;
		}
	}
	
	private String recuperaNomeCliente(Integer id){
		try {
			Object retorno = entityManager.createNativeQuery("select dsc_nome from cliente where id_cliente = :id")
				.setParameter("id", id)
				.getSingleResult();
			return retorno != null ? retorno.toString() : null;
		} catch (NoResultException e) {
			return null;
		}
	}

	public void setListaPedidos(List<Pedido> listaPedidos) {
		this.listaPedidos = listaPedidos;
	}
	
	public void fecharPopupAviso(){
		setExibePopupAviso(false);
	}
	
	public void salvar(){
		if(empresaSessao == null){
			return;
		}
		if(getPedidoEdicao().getFormaPagamento() == null ||
				getPedidoEdicao().getFormaPagamento().getIdFormaPagamento() == null){
			FacesMessages.instance().add(Severity.ERROR,"Selecione a forma de pagamento.");
			return;
		}
		
		boolean isEdicao = getPedidoEdicao().getIdPedido() != null;
		getPedidoEdicao().setEmpresa(empresaSessao);
		if(isPacote()){
			getPedidoEdicao().setVlrPedido(0F);
			getPedidoEdicao().setPacote(getPacoteDisponivel());
			getPedidoEdicao().setFlgPago('T');
			List<Pedido> pedidosPacote = entityManager.createQuery("select p from Pedido p where p.empresa.idEmpresa = :idEmpresa and p.pacote.idPacote = :idPacote").
				setParameter("idPacote", getPacoteDisponivel().getIdPacote())
				.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
				.getResultList();
			if(!isEdicao || getPedidoEdicao().getNroPedidoPacote() == null){
				getPedidoEdicao().setNroPedidoPacote(pedidosPacote.size() + 1);
			}
			if(getPedidoEdicao().getNroPedidoPacote() >= 4){
				setExibePopupAviso(true);
			}
		}else if(getPedidoEdicao().getVlrPedido() == null || getPedidoEdicao().getVlrPedido() == 0){
			FacesMessages.instance().add(Severity.ERROR,"O valor do pedido tem que ser maior do que 0.");
			return;
		}
		
		if(getPedidoEdicao().getFlgPago() == null){
			FacesMessages.instance().add(Severity.ERROR,"O campo PAGO? é de preenchimento obrigatório");
			return;
		}
		
		if(getPedidoEdicao().getCliente() == null ||
				getPedidoEdicao().getCliente().getIdCliente() == null){
			FacesMessages.instance().add(Severity.ERROR,"O campo Cliente é de preenchimento obrigatório");
			return;
		}
		
		for(PedidoProduto p : getListaPedidoProdutos()){
			if(p.getProduto() != null && p.getProduto().getIdProduto() != null 
					&& !PRODUTO_NAO_ENCONTRADO.equals(p.getProduto().getDscNome()) &&
					p.getQtdeProduto() > p.getProduto().getQtdEstoque()){
				FacesMessages.instance().add(Severity.ERROR,"Você não possui em estoque "+p.getQtdeProduto()+" quantidade(s) do produto(s): "+p.getProduto().getDscNome()+".");
				return;
			}
		}
		Pedido pedidoSalvo = entityManager.merge(getPedidoEdicao());
		for(PedidoServico s : getListaPedidoServicos()){
			s.setPedido(pedidoSalvo);
			entityManager.merge(s);
		}
		
		for(PedidoProduto p : getListaPedidoProdutos()){
			if(p.getProduto() != null && p.getProduto().getIdProduto() != null){
				if(!isEdicao){
					Produto prodSalvo = entityManager.find(Produto.class, p.getProduto().getIdProduto());
					prodSalvo.setQtdEstoque(prodSalvo.getQtdEstoque() - p.getQtdeProduto());
					entityManager.merge(prodSalvo);
				}
				p.setPedido(pedidoSalvo);
				entityManager.merge(p);
			}
		}
		
		for(PedidoProduto pe : produtosExclusao){
			if(pe.getIdPedidoProduto() != null){
				entityManager.remove(pe);
			}
		}
		
		for(PedidoServico se : servicosExclusao){
			if(se.getIdPedidoServico() != null){
				entityManager.remove(se);
			}
		}
		
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Pedido salvo com sucesso.");
		setListaPedidoProdutos(new ArrayList<PedidoProduto>());
		setListaPedidoServicos(new ArrayList<PedidoServico>());
		setListaPedidos(null);
		setPacoteDisponivel(null);
		setPacote(false);
		setValorRecebido(null);
		onLoad();
	}

	public List<Servico> autocomplete(Object suggest) {
        String pref = (String)suggest;
        List<Servico> result = new ArrayList<Servico>();
        if(empresaSessao != null){
	        List<Servico> servicos = entityManager.createQuery(QRY_SERVICOS)
	        	.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
	        	.getResultList();
	        
	        Iterator<Servico> iterator = servicos.iterator();
	        while (iterator.hasNext()) {
	            Servico elem = ((Servico) iterator.next());
	            if ((elem.getDscNome() != null && elem.getDscNome().toLowerCase().indexOf(pref.toLowerCase()) == 0) || "".equals(pref))
	            {
	                result.add(elem);
	            }
	        }
        }
        return result;
	}
	
	public Integer getNumeroPedido() {
		if(numeroPedido == null){
			numeroPedido = 1;
		}
		for(Pedido p : getListaPedidos()){
			if(numeroPedido < p.getNroPedido()){
				numeroPedido = p.getNroPedido();
			}
		}
		return numeroPedido;
	}

	public void setNumeroPedido(Integer numeroPedido) {
		this.numeroPedido = numeroPedido;
	}

	public PedidoPet getPedidoPet() {
		if (pedidoPet == null) {
			pedidoPet = new PedidoPet(new Pedido(),new Pet());
		}
		return pedidoPet;
	}

	public void setPedidoPet(PedidoPet pedidoPet) {
		this.pedidoPet = pedidoPet;
	}

	public Cliente getClienteSelecionado() {
		if (clienteSelecionado == null) {
			clienteSelecionado = new Cliente();
		}
		return clienteSelecionado;
	}

	public void setClienteSelecionado(Cliente clienteSelecionado) {
		this.clienteSelecionado = clienteSelecionado;
	}

	public Date getDataPedido() {
		if (dataPedido == null) {
			dataPedido = new Date();
		}
		return dataPedido;
	}

	public void setDataPedido(Date dataPedido) {
		this.dataPedido = dataPedido;
	}

	public Cliente getClienteDetalhe() {
		if (clienteDetalhe == null) {
			clienteDetalhe = new Cliente();
		}
		return clienteDetalhe;
	}

	public void setClienteDetalhe(Cliente clienteDetalhe) {
		this.clienteDetalhe = clienteDetalhe;
	}

	public List<PedidoServico> getListaPedidoServicos() {
		if (listaPedidoServicos == null) {
			listaPedidoServicos = new ArrayList<PedidoServico>();
		}
		return listaPedidoServicos;
	}

	public void setListaPedidoServicos(List<PedidoServico> listaPedidoServicos) {
		this.listaPedidoServicos = listaPedidoServicos;
	}

	public List<PedidoProduto> getListaPedidoProdutos() {
		if (listaPedidoProdutos == null) {
			listaPedidoProdutos = new ArrayList<PedidoProduto>();
		}
		return listaPedidoProdutos;
	}

	public void setListaPedidoProdutos(List<PedidoProduto> listaPedidoProdutos) {
		this.listaPedidoProdutos = listaPedidoProdutos;
	}
	
	public void novoServico(){
		getListaPedidoServicos().add(new PedidoServico(new Servico(),new Pedido(), new Pet(), true));
	}
	
	public void novoProduto(){
		getListaPedidoProdutos().add(new PedidoProduto(new Produto(), new Pedido(), 1));
	}
	
	public boolean isSelecionadoTodosServicos() {
		return selecionadoTodosServicos;
	}

	public void setSelecionadoTodosServicos(boolean selecionadoTodosServicos) {
		this.selecionadoTodosServicos = selecionadoTodosServicos;
	}

	public boolean isSelecionadoTodosProdutos() {
		return selecionadoTodosProdutos;
	}

	public void setSelecionadoTodosProdutos(boolean selecionadoTodosProdutos) {
		this.selecionadoTodosProdutos = selecionadoTodosProdutos;
	}

	public boolean isSelecionadoTodosPedidos() {
		return selecionadoTodosPedidos;
	}

	public void setSelecionadoTodosPedidos(boolean selecionadoTodosPedidos) {
		this.selecionadoTodosPedidos = selecionadoTodosPedidos;
	}

	public void selecionaTodosServicos(){
		for(PedidoServico s : getListaPedidoServicos()){
			if(isSelecionadoTodosServicos()){
				s.setSelecionado(true);
			}else{
				s.setSelecionado(false);
			}
		}
	}
	
	public void selecionaTodosProdutos(){
		for(PedidoProduto s : getListaPedidoProdutos()){
			if(isSelecionadoTodosProdutos()){
				s.setSelecionado(true);
			}else{
				s.setSelecionado(false);
			}
		}
	}
	
	public void selecionaTodosPedidos(){
		for(Pedido p : getListaPedidos()){
			if(isSelecionadoTodosPedidos()){
				p.setSelecionado(true);
			}else{
				p.setSelecionado(false);
			}
		}
	}
	
	public void editar(Pedido pedido){
		pedidoEdicao = entityManager.find(Pedido.class, pedido.getIdPedido());
		setListaPedidoProdutos(entityManager.createQuery(QRY_PRODUTOS_PEDIDO)
				.setParameter(PARAMETER_ID_PEDIDO, pedidoEdicao.getIdPedido())
				.getResultList());
		setListaPedidoServicos(entityManager.createQuery(QRY_SERVICOS_PEDIDO)
				.setParameter(PARAMETER_ID_PEDIDO, pedidoEdicao.getIdPedido())
				.getResultList());
		List<Pet> pets = entityManager.createQuery(QRY_PETS)
			.setParameter(PARAMETER_ID_CLIENTE, pedidoEdicao.getCliente().getIdCliente())
			.getResultList();
		setListaPets(null);
		setPacote(getPedidoEdicao().getPacote() != null);
		if(isPacote()){
			setPacoteDisponivel(getPedidoEdicao().getPacote());
			getPedidoEdicao().setVlrPedido(0F);
		}
		for(Pet p : pets){
			getListaPets().add(new SelectItem(p.getIdPet(),p.getDscNome()));
		}
	}
	
	public void excluir(){
		List<Pedido> pedidosRemocao = new ArrayList<Pedido>();
		for(Pedido p : getListaPedidos()){
			if(p.isSelecionado()){
				List<PedidoProduto> pedidos = entityManager.createQuery(QRY_PRODUTOS_PEDIDO)
					.setParameter(PARAMETER_ID_PEDIDO, p.getIdPedido())
					.getResultList();
				for(PedidoProduto ped : pedidos){
					Produto prod = ped.getProduto();
					prod.setQtdEstoque(prod.getQtdEstoque() + ped.getQtdeProduto());
					entityManager.merge(prod);
					entityManager.remove(ped);
				}
				List<PedidoServico> servicos = entityManager.createQuery(QRY_SERVICOS_PEDIDO)
					.setParameter(PARAMETER_ID_PEDIDO, p.getIdPedido())
					.getResultList(); 
				for(PedidoServico ser : servicos){
					entityManager.remove(ser);
				}
				pedidosRemocao.add(p);
			}
		}
		getListaPedidos().removeAll(pedidosRemocao);
		for(Pedido ped : pedidosRemocao){
			entityManager.remove(entityManager.find(Pedido.class, ped.getIdPedido()));
		}
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Pedido(s) excluído(s) com sucesso.");
	}
	
	public void excluirProduto(){
		for(PedidoProduto prod : getListaPedidoProdutos()){
			if(prod.isSelecionado()){
				produtosExclusao.add(prod);
			}
		}
		getListaPedidoProdutos().removeAll(produtosExclusao);
		atualizaValorTotalPedido();
	}
	
	public void excluirServico(){
		for(PedidoServico serv : getListaPedidoServicos()){
			if(serv.isSelecionado()){
				servicosExclusao.add(serv);
			}
		}
		getListaPedidoServicos().removeAll(servicosExclusao);
		atualizaValorTotalPedido();
	}

	public Pacote getPacoteDisponivel() {
		return pacoteDisponivel;
	}

	public void setPacoteDisponivel(Pacote pacoteDisponivel) {
		this.pacoteDisponivel = pacoteDisponivel;
	}
	
	public void atualizaValorPacoteListener(ValueChangeEvent evento){
		pacote = (Boolean)evento.getNewValue();
		for(PedidoServico ps : getListaPedidoServicos()){
			atualizaValorServico(ps);
		}
	}
	
	public void pesquisarPedidos(){
		listaPedidos = new ArrayList<Pedido>();
		if(empresaSessao != null){
			List<Object[]> lista = entityManager.createNativeQuery(QRY_PEDIDOS_DO_DIA)
				.setParameter(PARAMETER_DTA_PEDIDO, getDataPedido())
				.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
				.getResultList();
			Pedido p;
			for(Object[] o : lista){
				p = new Pedido();
				p.setIdPedido(Integer.parseInt(o[0].toString()));
				p.setVlrPedido(o[3] != null ? Float.parseFloat(o[3].toString()) : null);
				p.setFlgPago(o[4] != null ? (Character)o[4] : null);
				FormaPagamento pf = new FormaPagamento();
				pf.setDscFormaPagamento(o[1] != null ? recuperaDescricaoFormaPagamento(Integer.parseInt(o[1].toString())) : null);
				pf.setIdFormaPagamento(o[1] != null ? Integer.parseInt(o[1].toString()) : null);
				p.setFormaPagamento(pf);
				Cliente c = new Cliente();
				c.setDscNome(o[2] != null ? recuperaNomeCliente(Integer.parseInt(o[2].toString())) : null);
				c.setIdCliente(o[2] != null ? Integer.parseInt(o[2].toString()) : null);
				p.setCliente(c);
				listaPedidos.add(p);
			}
		}
		/*listaPedidos = entityManager.createQuery(QRY_PEDIDOS_DO_DIA)
			.setParameter(PARAMETER_DTA_PEDIDO, getDataPedido())
			.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
			.getResultList();*/
	}
	
	public void pesquisarClientes(){
		StringBuffer query = new StringBuffer(QRY_CLIENTES);
		if(parametrosClientes.getCliente().getDscNome() != null &&
				!parametrosClientes.getCliente().getDscNome().isEmpty()){
			query.append(" and UPPER(c.dscNome) like UPPER('%"+parametrosClientes.getCliente().getDscNome()+"%')");
		}
		
		if(parametrosClientes.getCliente().getTelCelular() != null &&
				!parametrosClientes.getCliente().getTelCelular().isEmpty()){
			query.append(" and c.telCelular = :celular");
		}
		
		if(parametrosClientes.getCliente().getTelResidencial() != null &&
				!parametrosClientes.getCliente().getTelResidencial().isEmpty()){
			query.append(" and c.telResidencial = :residencial");
		}
		
		if(parametrosClientes.getCliente().getDscEndereco() != null &&
				!parametrosClientes.getCliente().getDscEndereco().isEmpty()){
			query.append(" and UPPER(c.dscEndereco) like UPPER('%"+parametrosClientes.getCliente().getDscEndereco()+"%')");
		}
		
		if(parametrosClientes.getCliente().getDscCidade() != null &&
				!parametrosClientes.getCliente().getDscCidade().isEmpty()){
			query.append(" and UPPER(c.dscCidade) = UPPER(:cidade)");
		}
		
		if(parametrosClientes.getNomePet() != null &&
				!parametrosClientes.getNomePet().isEmpty()){
			query.append(" and UPPER(p.dscNome) like UPPER('%"+parametrosClientes.getNomePet()+"%')");
		}
		
		query.append(" group by c.idCliente");
		
		Query qryResult = entityManager.createQuery(query.toString());
		
		qryResult.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa());
		
		if(parametrosClientes.getCliente().getTelCelular() != null &&
				!parametrosClientes.getCliente().getTelCelular().isEmpty()){
			qryResult.setParameter("celular", parametrosClientes.getCliente().getTelCelular());
		}
		
		if(parametrosClientes.getCliente().getTelResidencial() != null &&
				!parametrosClientes.getCliente().getTelResidencial().isEmpty()){
			qryResult.setParameter("residencial", parametrosClientes.getCliente().getTelResidencial());
		}
		
		
		if(parametrosClientes.getCliente().getDscCidade() != null &&
				!parametrosClientes.getCliente().getDscCidade().isEmpty()){
			qryResult.setParameter("cidade", parametrosClientes.getCliente().getDscCidade());
		}
		
		listaClientes = qryResult.getResultList();
		
	}
	
	public void selecionarCliente(Cliente cliente){
		getPedidoEdicao().setCliente(cliente);
		atualizaListaPets();
	}

	public OrdemServicoVO getOrdemServico() {
		return ordemServico;
	}

	public void setOrdemServico(OrdemServicoVO ordemServico) {
		this.ordemServico = ordemServico;
	}
	
	public String geraOrdemServico(Pedido pedidoSelecionado){
		Pedido pedido = entityManager.find(Pedido.class, pedidoSelecionado.getIdPedido());
		ordemServico = null;
		ordemServico = new OrdemServicoVO();
		ordemServico.setNumero(pedido.getNroPedido().toString());
		ordemServico.setNumeroPacote(pedido.getNroPedidoPacote());
		ordemServico.setDataPedido(UtilDate.getDataComoString(pedido.getDtaPedido(), UtilDate.FORMATO_DATA_PADRAO));
		ordemServico.setPacote(pedido.getPacote());
		List<PedidoServico> servicos = entityManager.createQuery(QRY_SERVICOS_PEDIDO)
			.setParameter(PARAMETER_ID_PEDIDO, pedido.getIdPedido())
			.getResultList();
//		StringBuffer pets = new StringBuffer();
//		List<Pet> listaPetsServico = new ArrayList<Pet>();
		for(PedidoServico p : servicos){
			p.setListaServicos(null);
		}
		for(PedidoServico p : servicos){
			if(ordemServico.getListaServicosPet().size() == 0){
//				listaPetsServico.add(p.getPet());
//				pets.append(p.getPet().getDscNome()+"; ");
				p.getListaServicos().add(p.getServico());
				ordemServico.getListaServicosPet().add(p);
			}else{
				int cont = 0;
				for(PedidoServico pet : ordemServico.getListaServicosPet()){
					if(pet.getPet().getDscNome().equals(p.getPet().getDscNome())){
						cont++;
						pet.getListaServicos().add(p.getServico());
					}
				}
				if(cont == 0){
					p.getListaServicos().add(p.getServico());
					ordemServico.getListaServicosPet().add(p);
				}
			}
		}
//		ordemServico.setNomeAnimal(pets.toString());
		ordemServico.setRaca(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().getRaca().getDscNome() : "N/A");
		//ordemServico.setSexo(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().get : "N/A");
		ordemServico.setNomeAnimal(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().getDscNome() : "N/A");
		ordemServico.setNomeProprietario(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().getCliente().getDscNome() : "N/A");
		ordemServico.setEndereco(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().getCliente().getDscEndereco() + ", " + servicos.get(0).getPet().getCliente().getDscCidade() : "N/A");
		ordemServico.setTelefones(servicos != null && servicos.size() > 0 ? servicos.get(0).getPet().getCliente().getTelCelular() + "/" + servicos.get(0).getPet().getCliente().getTelResidencial() : "N/A");
		StringBuffer servString = new StringBuffer();
		for(PedidoServico ps : servicos){
			servString.append(ps.getServico().getDscNome()+"; ");
		}
		ordemServico.setServicos(servString.toString());
		ordemServico.setValor("R$ "+ConversorMonetario.mascaraValor(pedido.getVlrPedido().toString()));
		ordemServico.setObservacoes(pedido.getDscObservacoes());
		return "ordemServico";
	}

	public Produto getProdutoPesquisa() {
		if (produtoPesquisa == null) {
			produtoPesquisa = new Produto();
		}
		return produtoPesquisa;
	}

	public void setProdutoPesquisa(Produto produtoPesquisa) {
		this.produtoPesquisa = produtoPesquisa;
	}
	
	public String getNomeServicoPesquisa() {
		return nomeServicoPesquisa;
	}

	public void setNomeServicoPesquisa(String nomeServicoPesquisa) {
		this.nomeServicoPesquisa = nomeServicoPesquisa;
	}
	
	public void pesquisarServicos(){
		if(empresaSessao == null){
			return;
		}
		StringBuffer query = new StringBuffer(QRY_SERVICOS);
		
		if(getNomeServicoPesquisa() != null &&
				!getNomeServicoPesquisa().isEmpty()){
			query.append(" and s.dscNome like :nome");
		}
		
		Query qryResult = entityManager.createQuery(query.toString());
		
		qryResult.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa());
		
		if(getNomeServicoPesquisa() != null &&
				!getNomeServicoPesquisa().isEmpty()){
			qryResult.setParameter("nome", "%"+getNomeServicoPesquisa()+"%");
		}
		
		listaServicos = qryResult.getResultList();
	}

	public void pesquisarProdutos(){
		StringBuffer query = new StringBuffer(QRY_PRODUTOS);
		
		if(getProdutoPesquisa().getDscNome() != null &&
				!getProdutoPesquisa().getDscNome().isEmpty()){
			query.append(" and p.dscNome like '%"+getProdutoPesquisa().getDscNome()+"%'");
		}
		
		if(getProdutoPesquisa().getDscFabricante() != null &&
				!getProdutoPesquisa().getDscFabricante().isEmpty()){
			query.append(" and p.dscFabricante like '%"+getProdutoPesquisa().getDscFabricante()+"%'");
		}
		
		if(getProdutoPesquisa().getDosagem() != null &&
				!getProdutoPesquisa().getDosagem().isEmpty()){
			query.append(" and p.dosagem = '"+getProdutoPesquisa().getDosagem()+"'");
		}
		listaProdutos = entityManager.createQuery(query.toString())
			.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
			.getResultList();
		if(listaProdutos == null || listaProdutos.size() == 0){
			FacesMessages.instance().add(Severity.INFO,"Nenhum registro encontrado.");
		}
	}
	
	public void selecionarProduto(Produto produtoSelecionado){
		/*this.produtoSelecionado.setProduto(produtoSelecionado);
		PedidoProduto pedidoProduto = getListaPedidoProdutos().get(indexProduto);
		pedidoProduto.setProduto(produtoSelecionado);
		atualizaValorProduto(this.produtoSelecionado);*/
		
		if(produtoSelecionado.getDscNome().equals(PRODUTO_NAO_ENCONTRADO)){
			PedidoProduto pedidoProduto = getListaPedidoProdutos().get(
					indexProduto);
			pedidoProduto.setProduto(produtoSelecionado);
			return;
		}
		boolean quantidade = false;
		for (PedidoProduto pedidoProduto : getListaPedidoProdutos()) {
			if (pedidoProduto.getProduto().getDscNome() != null) {
				if ((pedidoProduto.getProduto().getDscNome()
						.equals(produtoSelecionado.getDscNome()))) {
					pedidoProduto
							.setQtdeProduto(pedidoProduto.getQtdeProduto() + 1);
					quantidade = true;
					this.produtoSelecionado.setProduto(new Produto());
					break;
				}
			}
		}
		if (!quantidade) {
			this.produtoSelecionado.setProduto(produtoSelecionado);
			PedidoProduto pedidoProduto = getListaPedidoProdutos().get(
					indexProduto);
			pedidoProduto.setProduto(produtoSelecionado);
			novoProduto();
		}
		atualizaValorProduto(this.produtoSelecionado);
		setValorRecebido(0.0F);
		setValorFinal(0.0F);
	}

	public PedidoProduto getProdutoSelecionado() {
		return produtoSelecionado;
	}

	public void setProdutoSelecionado(PedidoProduto produtoSelecionado) {
		this.produtoSelecionado = produtoSelecionado;
	}
	
	public void inicializaPopupProdutos(PedidoProduto produto, Integer index){
		this.produtoSelecionado = produto;
		indexProduto = index;
		setProdutoPesquisa(new Produto());
		setListaProdutos(new ArrayList<Produto>());
	}
	
	public void inicializaPopupServicos(PedidoServico servico){
		this.servicoSelecionado = servico;
//		indexProduto = index;
		setListaServicos(null);
		pesquisarServicos();
	}
	
	public void selecionaServico(Servico servico){
		this.servicoSelecionado.setServico(servico);
		atualizaValorServico(this.servicoSelecionado);
	}
	
	public void exibeDetalheCliente(Pedido pedidoSelecionado){
		this.clienteDetalhe = entityManager.find(Cliente.class, pedidoSelecionado.getCliente().getIdCliente());
	}
	
	public void buscaCodBarras(PedidoProduto produto, Integer index) {
		if (produto.getProduto().getCodBarras() != null
				&& !UtilString.isStringVazia(produto.getProduto()
						.getCodBarras())) {
			this.produtoSelecionado = produto;
			indexProduto = index;
			setProdutoPesquisa(new Produto());
			setListaProdutos(new ArrayList<Produto>());
			pesquisarProdutosCodigo(produto.getProduto().getCodBarras());
		}
	}
	
	public void pesquisarProdutosCodigo(String codBarras) {
		StringBuffer query = new StringBuffer(QRY_PRODUTOS);

		query.append(" and p.codBarras = :codBarras");
		try {
			Produto produto = (Produto) entityManager.createQuery(
					query.toString())
					.setParameter("codBarras", codBarras)
					.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
					.getSingleResult();
			/*if (produto.getQtdEstoque() < 1) {
				selecionarProduto(new Produto("PRODUTO SEM QTD NO ESTOQUE"));
			} else {*/
				selecionarProduto(produto);
//			}
		} catch (Exception e) {
			FacesMessages.instance().add(Severity.INFO,
					"Nenhum registro encontrado.");
			selecionarProduto(new Produto(PRODUTO_NAO_ENCONTRADO));
		}
	}
	
	public void atualizaValorFinal() {
		setValorFinal(getPedidoEdicao().getVlrPedido());
	}
	
	public void atualizaValorTotalTroco() {
		if (getValorRecebido() != null) {
			if (getValorRecebido() >= getPedidoEdicao().getVlrPedido()) {
				setValorFinal(getValorRecebido()
						- getPedidoEdicao().getVlrPedido());
				setAlert(null);
			} else {
				setValorFinal(0.0F);
				setValorRecebido(0.0F);
				setAlert("alert('Valor de troco inferior ao custo.')");
				return;
			}
		} else {
			setValorFinal(0.0F);
		}
	}
	
	public boolean exibeFinalizar(){
		if (getValorRecebido() != null && getPedidoEdicao().getVlrPedido() != null) {
			if (getValorRecebido() >= getPedidoEdicao().getVlrPedido()) {
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}

	public float getValorFinal() {
		return valorFinal;
	}

	public void setValorFinal(float valorFinal) {
		this.valorFinal = valorFinal;
	}

	public Float getValorRecebido() {
		return valorRecebido;
	}

	public void setValorRecebido(Float valorRecebido) {
		this.valorRecebido = valorRecebido;
	}
}

